<?php
define('UUID_FMTSTRING',  '%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x');
class Zendvn_UUID {
         private $timeLow =0; //The low field of the timestamp
         private $timeMid =0; // The middle field of the timestamp
         private $timeHightAndVersion =0; //The high field of the timestamp multiplexed with the version number
         private $clockSequenceLow =0;    // The high field of the clock sequence multiplexed with the variant
         private $clockSequenceHightAndReserved =0; //The low field of the clock sequence
         private $node = array();   //The spatially unique node identifier

        public  static function create() {

          // Get timestamp and convert it to UTC (based Oct 15, 1582).
          list($usec, $sec) = explode(' ', microtime());
          $t= ($sec * 10000000) + ($usec * 10) + 122192928000000000;
          $clockSequence= mt_rand();

          $uuid= new Zendvn_UUID();
          $uuid->timeLow= ($t & 0xFFFFFFFF);
          $uuid->timeMid= (($t >> 32) & 0xFFFF);
          $uuid->timeHightAndVersion= (($t >> 48) & 0x0FFF);
          $uuid->timeHightAndVersion |= (1 << 12);
          $uuid->clockSequenceLow= $clockSequence & 0xFF;
          $uuid->clockSequenceHightAndReserved= ($clockSequence & 0x3F00) >> 8;
          $uuid->clockSequenceHightAndReserved |= 0x80;

          $h= md5(php_uname());
          $uuid->node= array(
            hexdec(substr($h, 0x0, 2)),
            hexdec(substr($h, 0x2, 2)),
            hexdec(substr($h, 0x4, 2)),
            hexdec(substr($h, 0x6, 2)),
            hexdec(substr($h, 0x8, 2)),
            hexdec(substr($h, 0xB, 2))
          );

          return $uuid;
        }

     
        public static function fromString($str) {
          $uuid= new Zendvn_UUID();
          if (11 != sscanf(
            $str,
            UUID_FMTSTRING,
            $uuid->timeLow,
            $uuid->timeMid,
            $uuid->timeHightAndVersion,
            $uuid->clockSequenceLow,
            $uuid->clockSequenceHightAndReserved,
            $uuid->node[0],
            $uuid->node[1],
            $uuid->node[2],
            $uuid->node[3],
            $uuid->node[4],
            $uuid->node[5]
          )) {
            return false;
          }
          return $uuid;
        }

       
        function __toString() {
          return sprintf(
            UUID_FMTSTRING,
            $this->timeLow,
            $this->timeMid,
            $this->timeHightAndVersion,
            $this->clockSequenceHightAndReserved,
            $this->clockSequenceLow,
            $this->node[0],
            $this->node[1],
            $this->node[2],
            $this->node[3],
            $this->node[4],
            $this->node[5]
          );
        }
}
